package com.owen.cyclic.barrier.simple4;

import com.owen.cyclic.barrier.simple1.MyRunnable1;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

/**
 * 示例4：
 *   其中一个人等待中被打断了
 *
 *   输出的信息看着有点乱，给大家理一理。
 *   员工5遇到急事，拿起筷子就是吃，这样好么，当然不好，他这么做了，后
 *   面看他这么做了都跟着这么做（这种场景是不是很熟悉，有一个人拿起筷子先吃起来，其他人都跟着上了），直接不等其他人了，拿起筷子就开吃了。
 *   CyclicBarrier遇到这种情况就是这么处理的。
 *   前面4个员工都在await()处等待着，员工5也在await()上等待着，等了1秒（TimeUnit.SECONDS.sleep(1);），
 *   接了个电话，然后给员工5发送中断信号后（t.interrupt();），员工5的await()方法会触发InterruptedException异常，
 *   此时其他等待中的前4个员工，看着5开吃了，自己立即也不等了，内部从await()方法中触发BrokenBarrierException异常，然后也开吃了，
 *   后面的6/7/8/9/10员工来了以后发现大家都开吃了，自己也不等了，6-10员工调用await()直接抛出了BrokenBarrierException异常，
 *   然后继续向下。
 *
 *   结论：
 *   1. 内部有一个人把规则破坏了（接收到中断信号），其他人都不按规则来了，不会等待了
 *   2. 接收到中断信号的线程，await方法会出发InterruptedException异常，然后被唤醒向下运行
 *   3. 其他等待中或者后面到达的线程，会在await方法上触发BrokenBarrierException异常，然后继续运行
 */
public class Main4 {

    private static CyclicBarrier cyclicBarrier=new CyclicBarrier(10);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            int sleep=0;
            if(i==9){
                sleep=10;
            }
            Thread thread = new Thread(new MyRunnable4(cyclicBarrier, "员工" + i, sleep));
            thread.start();
            if(i==4){
                // 模拟员工4接了个电话，将自己等待吃饭给打断了
                TimeUnit.SECONDS.sleep(1);
                System.out.println("员工"+i+"，有点急事，我先开干了！");
                thread.interrupt();
                TimeUnit.SECONDS.sleep(2);
            }
        }
    }
}
